<?php


namespace App\Http\Controllers;

use App\Models\ZZMed\ZHospMember;
use App\Services\AuthService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\Traits\SmsHelper;

class AuthController extends Controller
{

    use SmsHelper;

    protected static $defaultPhotoUri = 'https://zz-med-pub.oss-cn-hangzhou.aliyuncs.com/shared/images/default/doc_logo.jpg';

    protected $authService;


    public function __construct(AuthService $authService)
    {
        $this->authService = $authService;
    }

    /**
     *  登录
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\JsonResponse|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
     * @throws \Exception
     */
    public function login(Request $request)
    {
        if ($request->input('username', '') == '') {
            return $this->error(40001, '请求参数有误，用户名不能为空');
        }

        if ($request->input('password', '') == '') {
            return $this->error(40002,'请求参数有误，密码不能为空');
        }

        $credentials = ['username' => $request->input('username'), 'password' => $request->input('password')];

        $user = $this->getLoginUserInfo($credentials);

        if (!$user) {
            return $this->error(40004, '账号信息不存在，请核对后重试');
        }
        // 验证密码
        if (!$this->validatePasswordOrCode($user, $credentials)) {
            return $this->error(40003, '登录失败，用户名或密码错误');
        }

        $userInfo = $this->authService->authTokenByUser($this->getClientAppInfo($request), $this->getClientIpsStr($request), $user);

        $token = $userInfo['access_token'] ?? '';

        if (!$token) {
            return $this->error(40003, '登录失败,请稍后重试');
        }

        $data = $this->handleLogin($token);

        return $this->success($data);
    }

    /**
     *   获取手机登陆的验证码
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
     */
    public function getLoginCode(Request $request)
    {
        $rules = [
            'cell' => [
                'required',
                'regex:/^1[345789][0-9]{9}$/',
            ]
        ];
        if (Validator::make($request->input(), $rules)->fails()) {
            return $this->error(40015, '请输入手机号或手机号格式错误！');
        }
        $cell = $request->input('cell');
        $this->sendSms($cell, 506, []);
        return $this->success([]);
    }

    /**
     *  通过手机号+验证码登陆
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\JsonResponse|\Illuminate\Http\Response|\Symfony\Component\HttpFoundation\Response
     * @throws \Exception
     */
    public function loginByCell(Request $request)
    {
        $rules = [
            'cell' => [
                'required',
                'regex:/^1[345789][0-9]{9}$/',
            ],
            'smscode' => 'required'
        ];

        if (Validator::make($request->input(), $rules)->fails()) {
            return $this->error(40015, '请填写手机号和验证码,确认并检查验证码是否正确！');
        }
        $credentials = ['cell' => $request->input('cell'), 'smscode' => $request->input('smscode')];

        $user = $this->getLoginUserInfo($credentials);

        if (!$user) {
            return $this->error(40004, '账号信息不存在，请核对后重试');
        }

        // 验证验证码
        if (!$this->validatePasswordOrCode($user, $credentials)) {
            return $this->error(40003, '登录失败，验证码输入错误');
        }

        $userInfo = $this->authService->authTokenByUser($this->getClientAppInfo($request), $this->getClientIpsStr($request), $user);

        $token = $userInfo['access_token'] ?? '';

        if (!$token) {
            return $this->error(40003, '登录失败,请稍后重试');
        }

        $data = $this->handleLogin($token);

        return $this->success($data);
    }

    //独立出 共同使用代码
    public function handleLogin($token)
    {

        $user = auth(AuthService::getGuard())->user();

        $doctorInfo = ZHospMember::retrieveDoctorInfoById($user->id);

        $data = [
            'user_id' => $user->id,
            'user_name' => $user->name,
            'user_type' => $user->member_type,
            'sex' => $user->sex,
            'hosp_id' => $user->hosp_id,
            'hosp_name' => $user->hospital,
            'dept_id' => $user->dept_id,
            'dept_name' => $user->department,
            'doc_role' => $user->group_role_id,
            'photo' => $doctorInfo['photo'] ?: self::$defaultPhotoUri,
            'terminal_flg' => 0,
            'center_id' => $user->center_id,
            'center_name' => $user->center_name,
            'cell' => $user->cell,
            'switch_center' => $doctorInfo['switch_center'],
            'access_token' => $token,
            'token_type' => 'bearer',
            'expires_in' => auth(AuthService::getGuard())->factory()->getTTL() * 60
        ];

        return $data;
    }

    /**
     *  支持用户名和密码登录，重写该方法
     * @param array $credentials
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|object|null
     */
    public function getLoginUserInfo(array $credentials)
    {

        $query = ZHospMember::query()->from('z_hosp_member as a')
            ->select('a.*', 'b.dept_id', 'c.name as hospital', 'e.name as department', 'c.id as center_id', 'c.name as center_name')
            ->leftJoin('z_hosp_member_dept as b', 'a.id', '=', 'b.hosp_member_id')
            ->leftJoin('z_hosp as c', 'c.id', '=', 'a.hosp_id')
            ->leftJoin('z_dept as d', 'd.id', '=', 'b.dept_id')
            ->leftJoin('z_t_dept as e', 'e.id', '=', 'd.t_dept_id');

        if (isset($credentials["cell"]) && isset($credentials["smscode"])) {
            //验证码登陆
            $query = $query->where(function ($query) use ($credentials) {
                $query->where('a.cell', $credentials['cell']);
            });
        } else {
            $query = $query->where(function ($query) use ($credentials) {
                $query->where('a.cell', $credentials['username'])
                    ->orWhere('a.login_id', $credentials['username']);
            });
        }
        return $query->where('a.member_type', 3)
            ->where('a.status', 0)->first();
    }


    /**
     *  支持用户名和密码登录，重写该方法 仅作为测试
     * @param $id
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|\Illuminate\Database\Query\Builder|object|null
     */
    public function getLoginUserInfoById($id)
    {

        return  ZHospMember::query()->from('z_hosp_member as a')
            ->select('a.*', 'b.dept_id', 'c.name as hospital', 'e.name as department', 'c.id as center_id', 'c.name as center_name')
            ->leftJoin('z_hosp_member_dept as b', 'a.id', '=', 'b.hosp_member_id')
            ->leftJoin('z_hosp as c', 'c.id', '=', 'a.hosp_id')
            ->leftJoin('z_dept as d', 'd.id', '=', 'b.dept_id')
            ->leftJoin('z_t_dept as e', 'e.id', '=', 'd.t_dept_id')
            ->where('a.id', $id)
            ->where('a.member_type', 3)
            ->where('a.status', 0)->first();
    }


    /**
     *  验证用户密码是否正确
     * @param  $user
     * @param array $credentials
     * @return bool
     */
    public function validatePasswordOrCode($user, array $credentials){

        if (isset($credentials["cell"]) && isset($credentials["smscode"])) {
            //验证码验证
            $res = $this->verifySmsCode($credentials["cell"], $credentials["smscode"], 506);
            if (isset($res[0]) && $res[0]) {
                return true;
            } else {
                return false;
            }
        } else {
            $plain = $credentials['password'];

            if (strlen($plain) === 0) {
                return false;
            }

            return md5($plain . ZHospMember::$PASSWORD_SALT) === $user->getAuthPassword();
        }
    }

    /**
     * 退出登录
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Symfony\Component\HttpFoundation\Response
     */
    public function logout()
    {
        auth(AuthService::getGuard())->logout();

        return $this->success([]);
    }

    /**
     *  获取医生信息
     * @param Request $request
     * @return \Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function me(Request $request)
    {
        $user_id = $request->query('user_id',0);

        // 测试使用
        $user = $this->getLoginUserInfoById($user_id);

        $token = auth('api')->login($user);

        $data = $this->handleLogin($token);

        return $this->success($data);

    }

    /**
     * 获取客户端ip 字符串 , 拼接
     * @param Request $request
     * @return string
     */
    protected function getClientIpsStr(Request $request)
    {
        return implode(',', $request->getClientIps());
    }
}
